package com.piece.core.authentication.provider;

import com.piece.core.authentication.exception.MobileNotMatchException;
import com.piece.core.web.authority.token.MobileAuthenticationToken;
import com.piece.core.framework.util.cache.CacheFactory;
import com.piece.core.web.properties.SecurityProperties;
import com.piece.core.framework.support.dto.UserDetailDTO;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetailsService;

public class AuthenticationMobileProvider implements AuthenticationProvider {

    private final String LOGIN_COUNT = "login_count_";

    private SecurityProperties securityProperties;

    private UserDetailsService userDetailsService;

    private CacheFactory cacheFactory;

    @Override
    public Authentication authenticate(Authentication authentication) {
        MobileAuthenticationToken authenticationToken = (MobileAuthenticationToken) authentication;
        String mobile = authenticationToken.getMobile();

        UserDetailDTO user = (UserDetailDTO) userDetailsService.loadUserByUsername(mobile);
        if (null == user) {
            throw new MobileNotMatchException();
        }

        // 登陆次数验证
        if (null != cacheFactory) {
            ProviderUtil.authLoginCount(cacheFactory, securityProperties, LOGIN_COUNT + mobile);
        }

        // 清空登陆次数统计
        if (null != cacheFactory) {
            cacheFactory.get().delete(LOGIN_COUNT + mobile);
        }

        MobileAuthenticationToken authenticationResult = new MobileAuthenticationToken(mobile, user, user.getAuthorities(), authenticationToken.getClientId());
        return authenticationResult;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return MobileAuthenticationToken.class.isAssignableFrom(authentication);
    }

    public void setSecurityProperties(SecurityProperties securityProperties) {
        this.securityProperties = securityProperties;
    }

    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    public void setCacheFactory(CacheFactory cacheFactory) {
        this.cacheFactory = cacheFactory;
    }
}
